/**
 * Copyright: Copyright (c)2011
 * Company: 易宝支付(YeePay)
 */
package net.loyintean.pearlshell.logcenter.db.impl;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import net.loyintean.pearlshell.logcenter.db.LoggerDBService;
import net.loyintean.pearlshell.logcenter.model.ILogModel;

/** 作为信息的生产者，并分发给消费者。
 * <p>
 * 日志记录
 * 
 * @author：jun.lin@yeepay.com
 * @since：2015年1月17日 下午2:40:52
 * @version: */
class LoggerDBDistributer implements LoggerDBService {

	/** logQueue : 分发的基础 */
	private static final List<ILogModel> logQueue = new LinkedList<ILogModel>();

	private static final ExecutorService EXECUTOR_SERVICE = Executors
			.newFixedThreadPool(4);

	/** distributeSize : 分发数据量阈值 */
	private int distributeSize = 10;

	/** @see net.loyintean.pearlshell.logcenter.db.LoggerDBService#saveLogger(net.loyintean.pearlshell.logcenter.model.ILogModel) */
	@Override
	public int saveLogger(ILogModel log) {
		assert log != null;

		synchronized (logQueue) {
			// 首先进行阈值判断和处理
			System.out.println(Thread.currentThread().getName()
					+ "=saveLogger=" + logQueue.size());
			validSize();

			// 然后写进来
			logQueue.add(log);

		}

		return 0;
	}

	private void validSize() {
		List<ILogModel> subLogList = null;
		// 二重加锁
		if (logQueue.size() >= distributeSize) {
			// 同一线程下，可以反复获取同一个锁
			synchronized (logQueue) {
				System.out.println(Thread.currentThread().getName()
						+ "=validSize=" + logQueue.size());

				if (logQueue.size() >= distributeSize) {
					subLogList = new ArrayList<ILogModel>(distributeSize);
					for (int i = 0; i < distributeSize; i++) {
						subLogList.add(logQueue.get(0));
						logQueue.remove(0);
					}
					// subLogList = logQueue.subList(0, distributeSize);
					// logQueue.removeAll(subLogList);

				}
			}
		}

		// 启动线程
		if (subLogList != null && !subLogList.isEmpty()) {
			LoggerDBBatchService batcher = new LoggerDBBatchService();
			batcher.setLogModelList(subLogList);
			EXECUTOR_SERVICE.submit(batcher);
		}

	}
}
